ಪೈಥಾನ್ನ ಹೈಪೋಥಿಸಿಸ್ ಲೈಬ್ರರಿಯೊಂದಿಗೆ ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ ಅನ್ವೇಷಿಸಿ. ಉದಾಹರಣೆ-ಆಧಾರಿತ ಪರೀಕ್ಷೆಗಳನ್ನು ಮೀರಿ, ಎಡ್ಜ್ ಕೇಸ್ಗಳನ್ನು ಹುಡುಕಿ ಮತ್ತು ಹೆಚ್ಚು ದೃಢವಾದ, ವಿಶ್ವಾಸಾರ್ಹ ಸಾಫ್ಟ್ವೇರ್ ನಿರ್ಮಿಸಿ.
ಯೂನಿಟ್ ಟೆಸ್ಟ್ಗಳನ್ನು ಮೀರಿ: ಪೈಥಾನ್ನ ಹೈಪೋಥಿಸಿಸ್ನೊಂದಿಗೆ ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ನ ಆಳವಾದ ಅವಲೋಕನ
ಸಾಫ್ಟ್ವೇರ್ ಅಭಿವೃದ್ಧಿಯ ಜಗತ್ತಿನಲ್ಲಿ, ಟೆಸ್ಟಿಂಗ್ (ಪರೀಕ್ಷೆ) ಗುಣಮಟ್ಟದ ಅಡಿಪಾಯವಾಗಿದೆ. ದಶಕಗಳಿಂದ, ಉದಾಹರಣೆ-ಆಧಾರಿತ ಟೆಸ್ಟಿಂಗ್ ಪ್ರಮುಖ ಮಾದರಿಯಾಗಿದೆ. ನಾವು ಇನ್ಪುಟ್ಗಳನ್ನು ಎಚ್ಚರಿಕೆಯಿಂದ ರಚಿಸುತ್ತೇವೆ, ನಿರೀಕ್ಷಿತ ಔಟ್ಪುಟ್ಗಳನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೇವೆ ಮತ್ತು ನಮ್ಮ ಕೋಡ್ ಯೋಜಿಸಿದಂತೆ ವರ್ತಿಸುತ್ತದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಲು ಅಸರ್ಶನ್ಗಳನ್ನು ಬರೆಯುತ್ತೇವೆ. unittest
ಮತ್ತು pytest
ನಂತಹ ಫ್ರೇಮ್ವರ್ಕ್ಗಳಲ್ಲಿ ಕಂಡುಬರುವ ಈ ವಿಧಾನವು ಶಕ್ತಿಯುತ ಮತ್ತು ಅತ್ಯಗತ್ಯವಾಗಿದೆ. ಆದರೆ, ನೀವು ಹುಡುಕಲು ಯೋಚಿಸದಂತಹ ಬಗ್ಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಬಲ್ಲ ಪೂರಕ ವಿಧಾನವೊಂದಿದೆ ಎಂದು ನಾನು ಹೇಳಿದರೆ?
ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ ಜಗತ್ತಿಗೆ ಸ್ವಾಗತ. ಇದು ನಿರ್ದಿಷ್ಟ ಉದಾಹರಣೆಗಳನ್ನು ಪರೀಕ್ಷಿಸುವುದರಿಂದ ನಿಮ್ಮ ಕೋಡ್ನ ಸಾಮಾನ್ಯ ಗುಣಲಕ್ಷಣಗಳನ್ನು (ಪ್ರಾಪರ್ಟಿಗಳನ್ನು) ಪರಿಶೀಲಿಸುವತ್ತ ಗಮನವನ್ನು ಬದಲಾಯಿಸುವ ಒಂದು ಮಾದರಿಯಾಗಿದೆ. ಮತ್ತು ಪೈಥಾನ್ ಪರಿಸರದಲ್ಲಿ, ಈ ವಿಧಾನದ ನಿರ್ವಿವಾದದ ಚಾಂಪಿಯನ್ ಹೈಪೋಥಿಸಿಸ್ ಎಂಬ ಲೈಬ್ರರಿಯಾಗಿದೆ.
ಈ ಸಮಗ್ರ ಮಾರ್ಗದರ್ಶಿಯು ನಿಮ್ಮನ್ನು ಸಂಪೂರ್ಣ ಆರಂಭಿಕ ಹಂತದಿಂದ ಹೈಪೋಥಿಸಿಸ್ನೊಂದಿಗೆ ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ನ ಆತ್ಮವಿಶ್ವಾಸದ ವೃತ್ತಿಪರರನ್ನಾಗಿ ಮಾಡುತ್ತದೆ. ನಾವು ಪ್ರಮುಖ ಪರಿಕಲ್ಪನೆಗಳನ್ನು ಅನ್ವೇಷಿಸುತ್ತೇವೆ, ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಗಳನ್ನು ಪರಿಶೀಲಿಸುತ್ತೇವೆ ಮತ್ತು ಹೆಚ್ಚು ದೃಢವಾದ, ವಿಶ್ವಾಸಾರ್ಹ ಮತ್ತು ಬಗ್-ನಿರೋಧಕ ಸಾಫ್ಟ್ವೇರ್ ನಿರ್ಮಿಸಲು ಈ ಶಕ್ತಿಶಾಲಿ ಸಾಧನವನ್ನು ನಿಮ್ಮ ದೈನಂದಿನ ಅಭಿವೃದ್ಧಿ ಕಾರ್ಯಪ್ರবাহದಲ್ಲಿ ಹೇಗೆ ಸಂಯೋಜಿಸುವುದು ಎಂದು ಕಲಿಯುತ್ತೇವೆ.
ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ ಎಂದರೇನು? ಮನಸ್ಥಿತಿಯಲ್ಲಿ ಒಂದು ಬದಲಾವಣೆ
ಹೈಪೋಥಿಸಿಸ್ ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು, ನಾವು ಮೊದಲು ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ನ ಮೂಲಭೂತ ಕಲ್ಪನೆಯನ್ನು ಗ್ರಹಿಸಬೇಕು. ನಮಗೆಲ್ಲರಿಗೂ ತಿಳಿದಿರುವ ಸಾಂಪ್ರದಾಯಿಕ ಉದಾಹರಣೆ-ಆಧಾರಿತ ಟೆಸ್ಟಿಂಗ್ಗೆ ಇದನ್ನು ಹೋಲಿಸೋಣ.
ಉದಾಹರಣೆ-ಆಧಾರಿತ ಟೆಸ್ಟಿಂಗ್: ಪರಿಚಿತ ಮಾರ್ಗ
ನೀವು my_sort()
ಎಂಬ ಕಸ್ಟಮ್ ಸಾರ್ಟಿಂಗ್ ಫಂಕ್ಷನ್ ಬರೆದಿದ್ದೀರಿ ಎಂದು ಊಹಿಸಿಕೊಳ್ಳಿ. ಉದಾಹರಣೆ-ಆಧಾರಿತ ಟೆಸ್ಟಿಂಗ್ನಲ್ಲಿ, ನಿಮ್ಮ ಆಲೋಚನಾ ಪ್ರಕ್ರಿಯೆ ಹೀಗಿರುತ್ತದೆ:
- "ಒಂದು ಸರಳ, ಕ್ರಮಬದ್ಧ ಪಟ್ಟಿಯೊಂದಿಗೆ ಪರೀಕ್ಷಿಸೋಣ." ->
assert my_sort([1, 2, 3]) == [1, 2, 3]
- "ವಿರುದ್ಧ ಕ್ರಮದಲ್ಲಿರುವ ಪಟ್ಟಿಯ ಬಗ್ಗೆ ಏನು?" ->
assert my_sort([3, 2, 1]) == [1, 2, 3]
- "ಖಾಲಿ ಪಟ್ಟಿಯ ಬಗ್ಗೆ ಹೇಗೆ?" ->
assert my_sort([]) == []
- "ನಕಲಿ ಅಂಶಗಳಿರುವ ಪಟ್ಟಿ?" ->
assert my_sort([5, 1, 5, 2]) == [1, 2, 5, 5]
- "ಮತ್ತು ಋಣಾತ್ಮಕ ಸಂಖ್ಯೆಗಳಿರುವ ಪಟ್ಟಿ?" ->
assert my_sort([-1, -5, 0]) == [-5, -1, 0]
ಇದು ಪರಿಣಾಮಕಾರಿಯಾಗಿದೆ, ಆದರೆ ಇದಕ್ಕೆ ಒಂದು ಮೂಲಭೂತ ಮಿತಿಯಿದೆ: ನೀವು ಯೋಚಿಸಬಹುದಾದ ಕೇಸ್ಗಳನ್ನು ಮಾತ್ರ ಪರೀಕ್ಷಿಸುತ್ತಿದ್ದೀರಿ. ನಿಮ್ಮ ಕಲ್ಪನೆಯಷ್ಟೇ ನಿಮ್ಮ ಪರೀಕ್ಷೆಗಳು ಉತ್ತಮವಾಗಿರುತ್ತವೆ. ನೀವು ಬಹು ದೊಡ್ಡ ಸಂಖ್ಯೆಗಳು, ಫ್ಲೋಟಿಂಗ್-ಪಾಯಿಂಟ್ ತಪ್ಪುಗಳು, ನಿರ್ದಿಷ್ಟ ಯುನಿಕೋಡ್ ಅಕ್ಷರಗಳು, ಅಥವಾ ಅನಿರೀಕ್ಷಿತ ವರ್ತನೆಗೆ ಕಾರಣವಾಗುವ ಡೇಟಾದ ಸಂಕೀರ್ಣ ಸಂಯೋಜನೆಗಳಂತಹ ಎಡ್ಜ್ ಕೇಸ್ಗಳನ್ನು ತಪ್ಪಿಸಿಕೊಳ್ಳಬಹುದು.
ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್: ಇನ್ವೇರಿಯಂಟ್ಗಳಲ್ಲಿ ಆಲೋಚಿಸುವುದು
ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ ಈ ವಿಧಾನವನ್ನು ತಿರುಗಿಸುತ್ತದೆ. ನಿರ್ದಿಷ್ಟ ಉದಾಹರಣೆಗಳನ್ನು ಒದಗಿಸುವ ಬದಲು, ನಿಮ್ಮ ಫಂಕ್ಷನ್ನ ಪ್ರಾಪರ್ಟಿಗಳು, ಅಥವಾ ಇನ್ವೇರಿಯಂಟ್ಗಳನ್ನು ನೀವು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೀರಿ—ಇವು ಯಾವುದೇ ಮಾನ್ಯವಾದ ಇನ್ಪುಟ್ಗೆ ಸತ್ಯವಾಗಿರಬೇಕಾದ ನಿಯಮಗಳು. ನಮ್ಮ my_sort()
ಫಂಕ್ಷನ್ಗೆ, ಈ ಪ್ರಾಪರ್ಟಿಗಳು ಹೀಗಿರಬಹುದು:
- ಔಟ್ಪುಟ್ ಸಾರ್ಟ್ ಆಗಿದೆ: ಯಾವುದೇ ಸಂಖ್ಯೆಗಳ ಪಟ್ಟಿಗೆ, ಔಟ್ಪುಟ್ ಪಟ್ಟಿಯಲ್ಲಿನ ಪ್ರತಿಯೊಂದು ಎಲಿಮೆಂಟ್ ಅದರ ನಂತರದ ಎಲಿಮೆಂಟ್ಗಿಂತ ಕಡಿಮೆ ಅಥವಾ ಸಮನಾಗಿರುತ್ತದೆ.
- ಔಟ್ಪುಟ್ ಇನ್ಪುಟ್ನಂತೆಯೇ ಅದೇ ಎಲಿಮೆಂಟ್ಗಳನ್ನು ಹೊಂದಿದೆ: ಸಾರ್ಟ್ ಮಾಡಿದ ಪಟ್ಟಿಯು ಮೂಲ ಪಟ್ಟಿಯ ಒಂದು ಪರ್ಮ್ಯುಟೇಷನ್ ಮಾತ್ರ; ಯಾವುದೇ ಎಲಿಮೆಂಟ್ಗಳು ಸೇರಿಸಲ್ಪಡುವುದಿಲ್ಲ ಅಥವಾ ಕಳೆದುಹೋಗುವುದಿಲ್ಲ.
- ಫಂಕ್ಷನ್ ಇಡೆಂಪೊಟೆಂಟ್ ಆಗಿದೆ: ಈಗಾಗಲೇ ಸಾರ್ಟ್ ಮಾಡಿದ ಪಟ್ಟಿಯನ್ನು ಮತ್ತೆ ಸಾರ್ಟ್ ಮಾಡುವುದರಿಂದ ಅದು ಬದಲಾಗಬಾರದು. ಅಂದರೆ,
my_sort(my_sort(some_list)) == my_sort(some_list)
.
ಈ ವಿಧಾನದೊಂದಿಗೆ, ನೀವು ಟೆಸ್ಟ್ ಡೇಟಾವನ್ನು ಬರೆಯುತ್ತಿಲ್ಲ. ನೀವು ನಿಯಮಗಳನ್ನು ಬರೆಯುತ್ತಿದ್ದೀರಿ. ನಂತರ, ಹೈಪೋಥಿಸಿಸ್ನಂತಹ ಫ್ರೇಮ್ವರ್ಕ್ಗೆ ನಿಮ್ಮ ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ತಪ್ಪೆಂದು ಸಾಬೀತುಪಡಿಸಲು ನೂರಾರು ಅಥವಾ ಸಾವಿರಾರು ಯಾದೃಚ್ಛಿಕ, ವೈವಿಧ್ಯಮಯ ಮತ್ತು ಕುತಂತ್ರದ ಇನ್ಪುಟ್ಗಳನ್ನು ರಚಿಸಲು ಬಿಡುತ್ತೀರಿ. ಅದು ಒಂದು ಪ್ರಾಪರ್ಟಿಯನ್ನು ಮುರಿಯುವ ಇನ್ಪುಟ್ ಅನ್ನು ಕಂಡುಕೊಂಡರೆ, ಅದು ಒಂದು ಬಗ್ ಅನ್ನು ಕಂಡುಕೊಂಡಿದೆ ಎಂದರ್ಥ.
ಹೈಪೋಥಿಸಿಸ್ ಪರಿಚಯ: ನಿಮ್ಮ ಸ್ವಯಂಚಾಲಿತ ಟೆಸ್ಟ್ ಡೇಟಾ ಜನರೇಟರ್
ಹೈಪೋಥಿಸಿಸ್ ಪೈಥಾನ್ನ ಪ್ರಮುಖ ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್ ಲೈಬ್ರರಿಯಾಗಿದೆ. ನೀವು ವ್ಯಾಖ್ಯಾನಿಸುವ ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ತೆಗೆದುಕೊಂಡು, ಅವುಗಳನ್ನು ಪರೀಕ್ಷಿಸಲು ಟೆಸ್ಟ್ ಡೇಟಾವನ್ನು ರಚಿಸುವ ಕಠಿಣ ಕೆಲಸವನ್ನು ಇದು ಮಾಡುತ್ತದೆ. ಇದು ಕೇವಲ ಒಂದು ಯಾದೃಚ್ಛಿಕ ಡೇಟಾ ಜನರೇಟರ್ ಅಲ್ಲ; ಇದು ದಕ್ಷತೆಯಿಂದ ಬಗ್ಗಳನ್ನು ಹುಡುಕಲು ವಿನ್ಯಾಸಗೊಳಿಸಲಾದ ಒಂದು ಬುದ್ಧಿವಂತ ಮತ್ತು ಶಕ್ತಿಯುತ ಸಾಧನವಾಗಿದೆ.
ಹೈಪೋಥಿಸಿಸ್ನ ಪ್ರಮುಖ ವೈಶಿಷ್ಟ್ಯಗಳು
- ಸ್ವಯಂಚಾಲಿತ ಟೆಸ್ಟ್ ಕೇಸ್ ಜನರೇಷನ್: ನಿಮಗೆ ಬೇಕಾದ ಡೇಟಾದ *ಆಕಾರವನ್ನು* ನೀವು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೀರಿ (ಉದಾ., "ಪೂರ್ಣಾಂಕಗಳ ಪಟ್ಟಿ," "ಕೇವಲ ಅಕ್ಷರಗಳನ್ನು ಹೊಂದಿರುವ ಸ್ಟ್ರಿಂಗ್," "ಭವಿಷ್ಯದ ದಿನಾಂಕ"), ಮತ್ತು ಹೈಪೋಥಿಸಿಸ್ ಆ ಆಕಾರಕ್ಕೆ ಅನುಗುಣವಾಗಿ ವೈವಿಧ್ಯಮಯ ಉದಾಹರಣೆಗಳನ್ನು ರಚಿಸುತ್ತದೆ.
- ಇಂಟೆಲಿಜೆಂಟ್ ಶ್ರಿಂಕಿಂಗ್: ಇದು ಇದರ ಮಾಂತ್ರಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಹೈಪೋಥಿಸಿಸ್ ವಿಫಲವಾದ ಟೆಸ್ಟ್ ಕೇಸ್ ಅನ್ನು ಕಂಡುಕೊಂಡಾಗ (ಉದಾ., ನಿಮ್ಮ ಸಾರ್ಟ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಕ್ರ್ಯಾಶ್ ಮಾಡುವ 50 ಸಂಕೀರ್ಣ ಸಂಖ್ಯೆಗಳ ಪಟ್ಟಿ), ಅದು ಆ ಬೃಹತ್ ಪಟ್ಟಿಯನ್ನು ವರದಿ ಮಾಡುವುದಿಲ್ಲ. ಅದು ವೈಫಲ್ಯಕ್ಕೆ ಕಾರಣವಾಗುವ ಸಾಧ್ಯವಾದಷ್ಟು ಚಿಕ್ಕ ಉದಾಹರಣೆಯನ್ನು ಕಂಡುಹಿಡಿಯಲು ಇನ್ಪುಟ್ ಅನ್ನು ಬುದ್ಧಿವಂತಿಕೆಯಿಂದ ಮತ್ತು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸರಳಗೊಳಿಸುತ್ತದೆ. 50-ಎಲಿಮೆಂಟ್ಗಳ ಪಟ್ಟಿಯ ಬದಲು, ಕೇವಲ
[inf, nan]
ನೊಂದಿಗೆ ವೈಫಲ್ಯ ಸಂಭವಿಸುತ್ತದೆ ಎಂದು ಅದು ವರದಿ ಮಾಡಬಹುದು. ಇದು ಡೀಬಗ್ಗಿಂಗ್ ಅನ್ನು ಅತ್ಯಂತ ವೇಗವಾಗಿ ಮತ್ತು ದಕ್ಷವಾಗಿಸುತ್ತದೆ. - ತಡೆರಹಿತ ಏಕೀಕರಣ: ಹೈಪೋಥಿಸಿಸ್
pytest
ಮತ್ತುunittest
ನಂತಹ ಜನಪ್ರಿಯ ಟೆಸ್ಟಿಂಗ್ ಫ್ರೇಮ್ವರ್ಕ್ಗಳೊಂದಿಗೆ ಸಂಪೂರ್ಣವಾಗಿ ಸಂಯೋಜನೆಗೊಳ್ಳುತ್ತದೆ. ನಿಮ್ಮ ಕಾರ್ಯಪ್ರবাহವನ್ನು ಬದಲಾಯಿಸದೆ, ನಿಮ್ಮ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಉದಾಹರಣೆ-ಆಧಾರಿತ ಪರೀಕ್ಷೆಗಳ ಜೊತೆಗೆ ಪ್ರಾಪರ್ಟಿ-ಆಧಾರಿತ ಪರೀಕ್ಷೆಗಳನ್ನು ಸೇರಿಸಬಹುದು. - ಸ್ಟ್ರಾಟೆಜಿಗಳ ಶ್ರೀಮಂತ ಲೈಬ್ರರಿ: ಇದು ಸರಳ ಪೂರ್ಣಾಂಕಗಳು ಮತ್ತು ಸ್ಟ್ರಿಂಗ್ಗಳಿಂದ ಹಿಡಿದು ಸಂಕೀರ್ಣ, ನೆಸ್ಟೆಡ್ ಡೇಟಾ ರಚನೆಗಳು, ಟೈಮ್ಝೋನ್-ಅರಿತ ಡೇಟ್ಟೈಮ್ಗಳು ಮತ್ತು ನಮ್ಪೈ ಅರೇಗಳವರೆಗೆ ಎಲ್ಲವನ್ನೂ ರಚಿಸಲು ಅಂತರ್ನಿರ್ಮಿತ "ಸ್ಟ್ರಾಟೆಜಿಗಳ" ಒಂದು ದೊಡ್ಡ ಸಂಗ್ರಹವನ್ನು ಹೊಂದಿದೆ.
- ಸ್ಟೇಟ್ಫುಲ್ ಟೆಸ್ಟಿಂಗ್: ಹೆಚ್ಚು ಸಂಕೀರ್ಣ ವ್ಯವಸ್ಥೆಗಳಿಗಾಗಿ, ಸ್ಟೇಟ್ ಟ್ರಾನ್ಸಿಶನ್ಗಳಲ್ಲಿನ ಬಗ್ಗಳನ್ನು ಕಂಡುಹಿಡಿಯಲು ಹೈಪೋಥಿಸಿಸ್ ಕ್ರಿಯೆಗಳ ಅನುಕ್ರಮಗಳನ್ನು ಪರೀಕ್ಷಿಸಬಲ್ಲದು, ಇದು ಉದಾಹರಣೆ-ಆಧಾರಿತ ಟೆಸ್ಟಿಂಗ್ನೊಂದಿಗೆ ಮಾಡುವುದು ಅತ್ಯಂತ ಕಷ್ಟಕರ.
ಪ್ರಾರಂಭಿಸುವುದು: ನಿಮ್ಮ ಮೊದಲ ಹೈಪೋಥಿಸಿಸ್ ಟೆಸ್ಟ್
ಕೆಲಸಕ್ಕೆ ಇಳಿಯೋಣ. ಹೈಪೋಥಿಸಿಸ್ ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಉತ್ತಮ ಮಾರ್ಗವೆಂದರೆ ಅದನ್ನು ಕ್ರಿಯೆಯಲ್ಲಿ ನೋಡುವುದು.
ಅನುಸ್ಥಾಪನೆ
ಮೊದಲಿಗೆ, ನೀವು ಹೈಪೋಥಿಸಿಸ್ ಮತ್ತು ನಿಮ್ಮ ಆಯ್ಕೆಯ ಟೆಸ್ಟ್ ರನ್ನರ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ (ನಾವು pytest
ಅನ್ನು ಬಳಸುತ್ತೇವೆ). ಇದು ತುಂಬಾ ಸರಳ:
pip install pytest hypothesis
ಒಂದು ಸರಳ ಉದಾಹರಣೆ: ಅಬ್ಸಲ್ಯೂಟ್ ವ್ಯಾಲ್ಯೂ ಫಂಕ್ಷನ್
ಒಂದು ಸಂಖ್ಯೆಯ ಅಬ್ಸಲ್ಯೂಟ್ ವ್ಯಾಲ್ಯೂವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡಬೇಕಾದ ಒಂದು ಸರಳ ಫಂಕ್ಷನ್ ಅನ್ನು ಪರಿಗಣಿಸೋಣ. ಸ್ವಲ್ಪ ದೋಷಪೂರಿತವಾದ ಅಳವಡಿಕೆ ಹೀಗಿರಬಹುದು:
# `my_math.py` ಎಂಬ ಫೈಲ್ನಲ್ಲಿ def custom_abs(x): """ಅಬ್ಸಲ್ಯೂಟ್ ವ್ಯಾಲ್ಯೂ ಫಂಕ್ಷನ್ನ ಕಸ್ಟಮ್ ಅಳವಡಿಕೆ.""" if x < 0: return -x return x
ಈಗ, test_my_math.py
ಎಂಬ ಟೆಸ್ಟ್ ಫೈಲ್ ಬರೆಯೋಣ. ಮೊದಲು, ಸಾಂಪ್ರದಾಯಿಕ pytest
ವಿಧಾನ:
# test_my_math.py (ಉದಾಹರಣೆ-ಆಧಾರಿತ) def test_abs_positive(): assert custom_abs(5) == 5 def test_abs_negative(): assert custom_abs(-5) == 5 def test_abs_zero(): assert custom_abs(0) == 0
ಈ ಪರೀಕ್ಷೆಗಳು ಪಾಸ್ ಆಗುತ್ತವೆ. ಈ ಉದಾಹರಣೆಗಳ ಆಧಾರದ ಮೇಲೆ ನಮ್ಮ ಫಂಕ್ಷನ್ ಸರಿಯಾಗಿ ಕಾಣುತ್ತದೆ. ಆದರೆ ಈಗ, ಹೈಪೋಥಿಸಿಸ್ನೊಂದಿಗೆ ಪ್ರಾಪರ್ಟಿ-ಆಧಾರಿತ ಪರೀಕ್ಷೆಯನ್ನು ಬರೆಯೋಣ. ಅಬ್ಸಲ್ಯೂಟ್ ವ್ಯಾಲ್ಯೂ ಫಂಕ್ಷನ್ನ ಒಂದು ಪ್ರಮುಖ ಪ್ರಾಪರ್ಟಿ ಯಾವುದು? ಫಲಿತಾಂಶವು ಎಂದಿಗೂ ಋಣಾತ್ಮಕವಾಗಿರಬಾರದು.
# test_my_math.py (ಹೈಪೋಥಿಸಿಸ್ನೊಂದಿಗೆ ಪ್ರಾಪರ್ಟಿ-ಆಧಾರಿತ) from hypothesis import given from hypothesis import strategies as st from my_math import custom_abs @given(st.integers()) def test_abs_property_is_non_negative(x): """ಪ್ರಾಪರ್ಟಿ: ಯಾವುದೇ ಪೂರ್ಣಾಂಕದ ಅಬ್ಸಲ್ಯೂಟ್ ವ್ಯಾಲ್ಯೂ ಯಾವಾಗಲೂ >= 0 ಆಗಿರುತ್ತದೆ.""" assert custom_abs(x) >= 0
ಇದನ್ನು ವಿಭಜಿಸೋಣ:
from hypothesis import given, strategies as st
: ನಾವು ಅಗತ್ಯವಾದ ಕಾಂಪೊನೆಂಟ್ಗಳನ್ನು ಇಂಪೋರ್ಟ್ ಮಾಡುತ್ತೇವೆ.given
ಒಂದು ಡೆಕೋರೇಟರ್ ಆಗಿದ್ದು, ಅದು ಸಾಮಾನ್ಯ ಟೆಸ್ಟ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಪ್ರಾಪರ್ಟಿ-ಆಧಾರಿತ ಪರೀಕ್ಷೆಯಾಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ.strategies
ಎಂಬುದು ನಮ್ಮ ಡೇಟಾ ಜನರೇಟರ್ಗಳನ್ನು ನಾವು ಕಂಡುಕೊಳ್ಳುವ ಮಾಡ್ಯೂಲ್ ಆಗಿದೆ.@given(st.integers())
: ಇದು ಪರೀಕ್ಷೆಯ ತಿರುಳು.@given
ಡೆಕೋರೇಟರ್ ಹೈಪೋಥಿಸಿಸ್ಗೆ ಈ ಟೆಸ್ಟ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಹಲವು ಬಾರಿ ಚಲಾಯಿಸಲು ಹೇಳುತ್ತದೆ. ಪ್ರತಿ ರನ್ಗೆ, ಅದು ಒದಗಿಸಿದ ಸ್ಟ್ರಾಟೆಜಿ,st.integers()
ಬಳಸಿ ಒಂದು ಮೌಲ್ಯವನ್ನು ರಚಿಸುತ್ತದೆ ಮತ್ತು ಅದನ್ನು ನಮ್ಮ ಟೆಸ್ಟ್ ಫಂಕ್ಷನ್ಗೆx
ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ರವಾನಿಸುತ್ತದೆ.assert custom_abs(x) >= 0
: ಇದು ನಮ್ಮ ಪ್ರಾಪರ್ಟಿ. ಹೈಪೋಥಿಸಿಸ್ ಯಾವುದೇ ಪೂರ್ಣಾಂಕx
ಅನ್ನು ಸೃಷ್ಟಿಸಿದರೂ, ನಮ್ಮ ಫಂಕ್ಷನ್ನ ಫಲಿತಾಂಶವು ಸೊನ್ನೆಗಿಂತ ಹೆಚ್ಚಾಗಿರಬೇಕು ಅಥವಾ ಸಮನಾಗಿರಬೇಕು ಎಂದು ನಾವು ದೃಢಪಡಿಸುತ್ತೇವೆ.
ನೀವು ಇದನ್ನು pytest
ನೊಂದಿಗೆ ಚಲಾಯಿಸಿದಾಗ, ಇದು ಅನೇಕ ಮೌಲ್ಯಗಳಿಗೆ ಪಾಸ್ ಆಗುವ ಸಾಧ್ಯತೆಯಿದೆ. ಹೈಪೋಥಿಸಿಸ್ 0, -1, 1, ದೊಡ್ಡ ಧನಾತ್ಮಕ ಸಂಖ್ಯೆಗಳು, ದೊಡ್ಡ ಋಣಾತ್ಮಕ ಸಂಖ್ಯೆಗಳು ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ಪ್ರಯತ್ನಿಸುತ್ತದೆ. ನಮ್ಮ ಸರಳ ಫಂಕ್ಷನ್ ಇವೆಲ್ಲವನ್ನೂ ಸರಿಯಾಗಿ ನಿರ್ವಹಿಸುತ್ತದೆ. ಈಗ, ದೌರ್ಬಲ್ಯವನ್ನು ಕಂಡುಹಿಡಿಯಬಹುದೇ ಎಂದು ನೋಡಲು ಬೇರೆ ಸ್ಟ್ರಾಟೆಜಿಯನ್ನು ಪ್ರಯತ್ನಿಸೋಣ.
# ಫ್ಲೋಟಿಂಗ್ ಪಾಯಿಂಟ್ ಸಂಖ್ಯೆಗಳೊಂದಿಗೆ ಪರೀಕ್ಷಿಸೋಣ @given(st.floats()) def test_abs_floats_property(x): assert custom_abs(x) >= 0
ನೀವು ಇದನ್ನು ಚಲಾಯಿಸಿದರೆ, ಹೈಪೋಥಿಸಿಸ್ ಶೀಘ್ರವಾಗಿ ವಿಫಲವಾದ ಕೇಸ್ ಅನ್ನು ಕಂಡುಕೊಳ್ಳುತ್ತದೆ!
Falsifying example: test_abs_floats_property(x=nan) ... assert custom_abs(nan) >= 0 AssertionError: assert nan >= 0
float('nan')
(ಸಂಖ್ಯೆಯಲ್ಲ) ನೀಡಿದಾಗ, ನಮ್ಮ ಫಂಕ್ಷನ್ nan
ಅನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ ಎಂದು ಹೈಪೋಥಿಸಿಸ್ ಕಂಡುಹಿಡಿದಿದೆ. nan >= 0
ಎಂಬ ಅಸರ್ಶನ್ ತಪ್ಪು. ನಾವು ಹಸ್ತಚಾಲಿತವಾಗಿ ಪರೀಕ್ಷಿಸಲು ಯೋಚಿಸದಂತಹ ಒಂದು ಸೂಕ್ಷ್ಮ ಬಗ್ ಅನ್ನು ನಾವು ಇದೀಗ ಕಂಡುಕೊಂಡಿದ್ದೇವೆ. ಈ ಕೇಸ್ ಅನ್ನು ನಿಭಾಯಿಸಲು ನಾವು ನಮ್ಮ ಫಂಕ್ಷನ್ ಅನ್ನು ಸರಿಪಡಿಸಬಹುದು, ಬಹುಶಃ ValueError
ಅನ್ನು ರೈಸ್ ಮಾಡುವ ಮೂಲಕ ಅಥವಾ ನಿರ್ದಿಷ್ಟ ಮೌಲ್ಯವನ್ನು ಹಿಂದಿರುಗಿಸುವ ಮೂಲಕ.
ಇನ್ನೂ ಉತ್ತಮ, ಒಂದು ವೇಳೆ ಬಗ್ ಬಹಳ ನಿರ್ದಿಷ್ಟವಾದ ಫ್ಲೋಟ್ನೊಂದಿಗೆ ಇದ್ದಿದ್ದರೆ? ಹೈಪೋಥಿಸಿಸ್ನ ಶ್ರಿಂಕರ್ ಒಂದು ದೊಡ್ಡ, ಸಂಕೀರ್ಣ ವಿಫಲ ಸಂಖ್ಯೆಯನ್ನು ತೆಗೆದುಕೊಂಡು ಅದನ್ನು ಬಗ್ ಅನ್ನು ಇನ್ನೂ ಪ್ರಚೋದಿಸುವ ಸರಳವಾದ ಆವೃತ್ತಿಗೆ ಇಳಿಸುತ್ತಿತ್ತು.
ಸ್ಟ್ರಾಟೆಜಿಗಳ ಶಕ್ತಿ: ನಿಮ್ಮ ಟೆಸ್ಟ್ ಡೇಟಾವನ್ನು ರಚಿಸುವುದು
ಸ್ಟ್ರಾಟೆಜಿಗಳು ಹೈಪೋಥಿಸಿಸ್ನ ಹೃದಯ. ಅವು ಡೇಟಾವನ್ನು ರಚಿಸುವ ಪಾಕವಿಧಾನಗಳಾಗಿವೆ. ಲೈಬ್ರರಿಯು ಅಂತರ್ನಿರ್ಮಿತ ಸ್ಟ್ರಾಟೆಜಿಗಳ ಒಂದು ದೊಡ್ಡ ಶ್ರೇಣಿಯನ್ನು ಒಳಗೊಂಡಿದೆ, ಮತ್ತು ನೀವು ಕಲ್ಪಿಸಿಕೊಳ್ಳಬಹುದಾದ ಯಾವುದೇ ಡೇಟಾ ರಚನೆಯನ್ನು ರಚಿಸಲು ನೀವು ಅವುಗಳನ್ನು ಸಂಯೋಜಿಸಬಹುದು ಮತ್ತು ಕಸ್ಟಮೈಸ್ ಮಾಡಬಹುದು.
ಸಾಮಾನ್ಯ ಅಂತರ್ನಿರ್ಮಿತ ಸ್ಟ್ರಾಟೆಜಿಗಳು
- ಸಾಂಖ್ಯಿಕ:
st.integers(min_value=0, max_value=1000)
: ಪೂರ್ಣಾಂಕಗಳನ್ನು ರಚಿಸುತ್ತದೆ, ಐಚ್ಛಿಕವಾಗಿ ನಿರ್ದಿಷ್ಟ ವ್ಯಾಪ್ತಿಯಲ್ಲಿ.st.floats(min_value=0.0, max_value=1.0, allow_nan=False, allow_infinity=False)
: ಫ್ಲೋಟ್ಗಳನ್ನು ರಚಿಸುತ್ತದೆ, ವಿಶೇಷ ಮೌಲ್ಯಗಳ ಮೇಲೆ ಸೂಕ್ಷ್ಮ ನಿಯಂತ್ರಣದೊಂದಿಗೆ.st.fractions()
,st.decimals()
- ಪಠ್ಯ:
st.text(min_size=1, max_size=50)
: ನಿರ್ದಿಷ್ಟ ಉದ್ದದ ಯುನಿಕೋಡ್ ಸ್ಟ್ರಿಂಗ್ಗಳನ್ನು ರಚಿಸುತ್ತದೆ.st.text(alphabet='abcdef0123456789')
: ನಿರ್ದಿಷ್ಟ ಅಕ್ಷರಗಳ ಗುಂಪಿನಿಂದ ಸ್ಟ್ರಿಂಗ್ಗಳನ್ನು ರಚಿಸುತ್ತದೆ (ಉದಾ., ಹೆಕ್ಸ್ ಕೋಡ್ಗಳಿಗಾಗಿ).st.characters()
: ಪ್ರತ್ಯೇಕ ಅಕ್ಷರಗಳನ್ನು ರಚಿಸುತ್ತದೆ.
- ಸಂಗ್ರಹಗಳು:
st.lists(st.integers(), min_size=1)
: ಪಟ್ಟಿಗಳನ್ನು ರಚಿಸುತ್ತದೆ, ಅಲ್ಲಿ ಪ್ರತಿ ಅಂಶವು ಪೂರ್ಣಾಂಕವಾಗಿರುತ್ತದೆ. ನಾವು ಇನ್ನೊಂದು ಸ್ಟ್ರಾಟೆಜಿಯನ್ನು ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ಹೇಗೆ ರವಾನಿಸುತ್ತೇವೆ ಎಂಬುದನ್ನು ಗಮನಿಸಿ! ಇದನ್ನು ಸಂಯೋಜನೆ ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ.st.tuples(st.text(), st.booleans())
: ಸ್ಥಿರ ರಚನೆಯೊಂದಿಗೆ ಟಪಲ್ಗಳನ್ನು ರಚಿಸುತ್ತದೆ.st.sets(st.integers())
st.dictionaries(keys=st.text(), values=st.integers())
: ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಕೀ ಮತ್ತು ವ್ಯಾಲ್ಯೂ ಪ್ರಕಾರಗಳೊಂದಿಗೆ ಡಿಕ್ಷನರಿಗಳನ್ನು ರಚಿಸುತ್ತದೆ.
- ಟೆಂಪೊರಲ್ (ಕಾಲಕ್ಕೆ ಸಂಬಂಧಿಸಿದ):
st.dates()
,st.times()
,st.datetimes()
,st.timedeltas()
. ಇವುಗಳನ್ನು ಟೈಮ್ಝೋನ್-ಅರಿತವಾಗಿ ಮಾಡಬಹುದು.
- ಇತರೆ:
st.booleans()
:True
ಅಥವಾFalse
ಅನ್ನು ರಚಿಸುತ್ತದೆ.st.just('constant_value')
: ಯಾವಾಗಲೂ ಒಂದೇ ಮೌಲ್ಯವನ್ನು ರಚಿಸುತ್ತದೆ. ಸಂಕೀರ್ಣ ಸ್ಟ್ರಾಟೆಜಿಗಳನ್ನು ರಚಿಸಲು ಉಪಯುಕ್ತ.st.one_of(st.integers(), st.text())
: ಒದಗಿಸಿದ ಸ್ಟ್ರಾಟೆಜಿಗಳಲ್ಲಿ ಒಂದರಿಂದ ಮೌಲ್ಯವನ್ನು ರಚಿಸುತ್ತದೆ.st.none()
: ಕೇವಲNone
ಅನ್ನು ರಚಿಸುತ್ತದೆ.
ಸ್ಟ್ರಾಟೆಜಿಗಳನ್ನು ಸಂಯೋಜಿಸುವುದು ಮತ್ತು ಪರಿವರ್ತಿಸುವುದು
ಹೈಪೋಥಿಸಿಸ್ನ ನಿಜವಾದ ಶಕ್ತಿಯು ಸರಳವಾದವುಗಳಿಂದ ಸಂಕೀರ್ಣ ಸ್ಟ್ರಾಟೆಜಿಗಳನ್ನು ನಿರ್ಮಿಸುವ ಸಾಮರ್ಥ್ಯದಲ್ಲಿದೆ.
.map()
ಬಳಸುವುದು
.map()
ಮೆಥೆಡ್ ಒಂದು ಸ್ಟ್ರಾಟೆಜಿಯಿಂದ ಮೌಲ್ಯವನ್ನು ತೆಗೆದುಕೊಂಡು ಅದನ್ನು ಬೇರೆ ಯಾವುದಕ್ಕಾದರೂ ಪರಿವರ್ತಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ನಿಮ್ಮ ಕಸ್ಟಮ್ ಕ್ಲಾಸ್ಗಳ ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು ರಚಿಸಲು ಇದು ಪರಿಪೂರ್ಣವಾಗಿದೆ.
# ಒಂದು ಸರಳ ಡೇಟಾ ಕ್ಲಾಸ್ from dataclasses import dataclass @dataclass class User: user_id: int username: str # User ಆಬ್ಜೆಕ್ಟ್ಗಳನ್ನು ರಚಿಸಲು ಒಂದು ಸ್ಟ್ರಾಟೆಜಿ user_strategy = st.builds( User, user_id=st.integers(min_value=1), username=st.text(min_size=3, alphabet='abcdefghijklmnopqrstuvwxyz') ) @given(user=user_strategy) def test_user_creation(user): assert isinstance(user, User) assert user.user_id > 0 assert user.username.isalpha()
.filter()
ಮತ್ತು assume()
ಬಳಸುವುದು
ಕೆಲವೊಮ್ಮೆ ನೀವು ರಚಿತವಾದ ಕೆಲವು ಮೌಲ್ಯಗಳನ್ನು ತಿರಸ್ಕರಿಸಬೇಕಾಗುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ನಿಮಗೆ ಮೊತ್ತವು ಸೊನ್ನೆಯಲ್ಲದ ಪೂರ್ಣಾಂಕಗಳ ಪಟ್ಟಿ ಬೇಕಾಗಬಹುದು. ನೀವು .filter()
ಅನ್ನು ಬಳಸಬಹುದು:
st.lists(st.integers()).filter(lambda x: sum(x) != 0)
ಆದಾಗ್ಯೂ, .filter()
ಬಳಸುವುದು ಅಸಮರ್ಥವಾಗಬಹುದು. ಷರತ್ತು ಆಗಾಗ್ಗೆ ತಪ್ಪಾಗಿದ್ದರೆ, ಮಾನ್ಯವಾದ ಉದಾಹರಣೆಯನ್ನು ರಚಿಸಲು ಹೈಪೋಥಿಸಿಸ್ ಬಹಳ ಸಮಯವನ್ನು ವ್ಯಯಿಸಬಹುದು. ಉತ್ತಮ ವಿಧಾನವೆಂದರೆ ನಿಮ್ಮ ಟೆಸ್ಟ್ ಫಂಕ್ಷನ್ನೊಳಗೆ assume()
ಅನ್ನು ಬಳಸುವುದು:
from hypothesis import assume @given(st.lists(st.integers())) def test_something_with_non_zero_sum_list(numbers): assume(sum(numbers) != 0) # ... ನಿಮ್ಮ ಟೆಸ್ಟ್ ತರ್ಕ ಇಲ್ಲಿ ...
assume()
ಹೈಪೋಥಿಸಿಸ್ಗೆ ಹೇಳುತ್ತದೆ: "ಈ ಷರತ್ತು ಪೂರೈಸದಿದ್ದರೆ, ಈ ಉದಾಹರಣೆಯನ್ನು ತಿರಸ್ಕರಿಸಿ ಮತ್ತು ಹೊಸದನ್ನು ಪ್ರಯತ್ನಿಸಿ." ಇದು ನಿಮ್ಮ ಟೆಸ್ಟ್ ಡೇಟಾವನ್ನು ನಿರ್ಬಂಧಿಸಲು ಹೆಚ್ಚು ನೇರ ಮತ್ತು ಸಾಮಾನ್ಯವಾಗಿ ಹೆಚ್ಚು ಕಾರ್ಯಕ್ಷಮತೆಯ ಮಾರ್ಗವಾಗಿದೆ.
st.composite()
ಬಳಸುವುದು
ಒಂದು ರಚಿತವಾದ ಮೌಲ್ಯವು ಇನ್ನೊಂದರ ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿರುವ ನಿಜವಾದ ಸಂಕೀರ್ಣ ಡೇಟಾ ಜನರೇಷನ್ಗಾಗಿ, st.composite()
ನಿಮಗೆ ಬೇಕಾದ ಸಾಧನವಾಗಿದೆ. ಇದು ವಿಶೇಷ draw
ಫಂಕ್ಷನ್ ಅನ್ನು ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ತೆಗೆದುಕೊಳ್ಳುವ ಫಂಕ್ಷನ್ ಅನ್ನು ಬರೆಯಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ, ಇದನ್ನು ನೀವು ಇತರ ಸ್ಟ್ರಾಟೆಜಿಗಳಿಂದ ಹಂತ-ಹಂತವಾಗಿ ಮೌಲ್ಯಗಳನ್ನು ಎಳೆಯಲು ಬಳಸಬಹುದು.
ಒಂದು ಕ್ಲಾಸಿಕ್ ಉದಾಹರಣೆಯೆಂದರೆ ಒಂದು ಪಟ್ಟಿ ಮತ್ತು ಆ ಪಟ್ಟಿಯ ಮಾನ್ಯವಾದ ಇಂಡೆಕ್ಸ್ ಅನ್ನು ರಚಿಸುವುದು.
@st.composite def list_and_index(draw): # ಮೊದಲು, ಖಾಲಿಯಿಲ್ಲದ ಪಟ್ಟಿಯನ್ನು ಡ್ರಾ ಮಾಡಿ my_list = draw(st.lists(st.integers(), min_size=1)) # ನಂತರ, ಆ ಪಟ್ಟಿಗೆ ಮಾನ್ಯವೆಂದು ಖಾತರಿಪಡಿಸಿದ ಇಂಡೆಕ್ಸ್ ಅನ್ನು ಡ್ರಾ ಮಾಡಿ index = draw(st.integers(min_value=0, max_value=len(my_list) - 1)) return (my_list, index) @given(data=list_and_index()) def test_list_access(data): my_list, index = data # ನಾವು ಸ್ಟ್ರಾಟೆಜಿಯನ್ನು ನಿರ್ಮಿಸಿದ ರೀತಿಯಿಂದ ಈ ಅಕ್ಸೆಸ್ ಸುರಕ್ಷಿತವೆಂದು ಖಾತರಿಪಡಿಸಲಾಗಿದೆ element = my_list[index] assert element is not None # ಒಂದು ಸರಳ ಅಸರ್ಶನ್
ಕ್ರಿಯೆಯಲ್ಲಿ ಹೈಪೋಥಿಸಿಸ್: ನೈಜ-ಪ್ರಪಂಚದ ಸನ್ನಿವೇಶಗಳು
ಸಾಫ್ಟ್ವೇರ್ ಡೆವಲಪರ್ಗಳು ಪ್ರತಿದಿನ ಎದುರಿಸುವ ಹೆಚ್ಚು ವಾಸ್ತವಿಕ ಸಮಸ್ಯೆಗಳಿಗೆ ಈ ಪರಿಕಲ್ಪನೆಗಳನ್ನು ಅನ್ವಯಿಸೋಣ.
ಸನ್ನಿವೇಶ 1: ಡೇಟಾ ಸೀರಿಯಲೈಸೇಶನ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಪರೀಕ್ಷಿಸುವುದು
ಒಂದು ಯೂಸರ್ ಪ್ರೊಫೈಲ್ (ಡಿಕ್ಷನರಿ) ಅನ್ನು URL-ಸುರಕ್ಷಿತ ಸ್ಟ್ರಿಂಗ್ಗೆ ಸೀರಿಯಲೈಸ್ ಮಾಡುವ ಫಂಕ್ಷನ್ ಮತ್ತು ಅದನ್ನು ಡಿಸೀರಿಯಲೈಸ್ ಮಾಡುವ ಇನ್ನೊಂದು ಫಂಕ್ಷನ್ ಅನ್ನು ಕಲ್ಪಿಸಿಕೊಳ್ಳಿ. ಪ್ರಮುಖ ಪ್ರಾಪರ್ಟಿ ಎಂದರೆ ಈ ಪ್ರಕ್ರಿಯೆಯು ಸಂಪೂರ್ಣವಾಗಿ ಹಿಂತಿರುಗಿಸಬಹುದಾದಂತಿರಬೇಕು.
import json import base64 def serialize_profile(data: dict) -> str: """ಒಂದು ಡಿಕ್ಷನರಿಯನ್ನು URL-ಸುರಕ್ಷಿತ base64 ಸ್ಟ್ರಿಂಗ್ಗೆ ಸೀರಿಯಲೈಸ್ ಮಾಡುತ್ತದೆ.""" json_string = json.dumps(data) return base64.urlsafe_b64encode(json_string.encode('utf-8')).decode('utf-8') def deserialize_profile(encoded_str: str) -> dict: """ಒಂದು ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಮತ್ತೆ ಡಿಕ್ಷನರಿಯಾಗಿ ಡಿಸೀರಿಯಲೈಸ್ ಮಾಡುತ್ತದೆ.""" json_string = base64.urlsafe_b64decode(encoded_str.encode('utf-8')).decode('utf-8') return json.loads(json_string) # ಈಗ ಪರೀಕ್ಷೆಗಾಗಿ # ನಮಗೆ JSON-ಹೊಂದಾಣಿಕೆಯ ಡಿಕ್ಷನರಿಗಳನ್ನು ರಚಿಸುವ ಸ್ಟ್ರಾಟೆಜಿ ಬೇಕು json_dictionaries = st.dictionaries( keys=st.text(), values=st.recursive(st.none() | st.booleans() | st.floats(allow_nan=False) | st.text(), lambda children: st.lists(children) | st.dictionaries(st.text(), children), max_leaves=10) ) @given(profile=json_dictionaries) def test_serialization_roundtrip(profile): """ಪ್ರಾಪರ್ಟಿ: ಎನ್ಕೋಡ್ ಮಾಡಿದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಡಿಸೀರಿಯಲೈಸ್ ಮಾಡಿದಾಗ ಮೂಲ ಪ್ರೊಫೈಲ್ ಹಿಂದಿರುಗಬೇಕು.""" encoded = serialize_profile(profile) decoded = deserialize_profile(encoded) assert profile == decoded
ಈ ಒಂದೇ ಪರೀಕ್ಷೆಯು ನಮ್ಮ ಫಂಕ್ಷನ್ಗಳನ್ನು ಬೃಹತ್ ವೈವಿಧ್ಯಮಯ ಡೇಟಾದೊಂದಿಗೆ ಪರೀಕ್ಷಿಸುತ್ತದೆ: ಖಾಲಿ ಡಿಕ್ಷನರಿಗಳು, ನೆಸ್ಟೆಡ್ ಪಟ್ಟಿಗಳಿರುವ ಡಿಕ್ಷನರಿಗಳು, ಯುನಿಕೋಡ್ ಅಕ್ಷರಗಳಿರುವ ಡಿಕ್ಷನರಿಗಳು, ವಿಚಿತ್ರ ಕೀಗಳನ್ನು ಹೊಂದಿರುವ ಡಿಕ್ಷನರಿಗಳು, ಮತ್ತು ಇನ್ನಷ್ಟು. ಇದು ಕೆಲವು ಹಸ್ತಚಾಲಿತ ಉದಾಹರಣೆಗಳನ್ನು ಬರೆಯುವುದಕ್ಕಿಂತ ಹೆಚ್ಚು ಸಂಪೂರ್ಣವಾಗಿದೆ.
ಸನ್ನಿವೇಶ 2: ಸಾರ್ಟಿಂಗ್ ಅಲ್ಗಾರಿದಮ್ ಅನ್ನು ಪರೀಕ್ಷಿಸುವುದು
ನಮ್ಮ ಸಾರ್ಟಿಂಗ್ ಉದಾಹರಣೆಯನ್ನು ಪುನಃ ನೋಡೋಣ. ನಾವು ಈ ಹಿಂದೆ ವ್ಯಾಖ್ಯಾನಿಸಿದ ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ನೀವು ಹೀಗೆ ಪರೀಕ್ಷಿಸಬಹುದು.
from collections import Counter def my_buggy_sort(numbers): # ಒಂದು ಸೂಕ್ಷ್ಮ ಬಗ್ ಅನ್ನು ಸೇರಿಸೋಣ: ಇದು ನಕಲಿಗಳನ್ನು ಕೈಬಿಡುತ್ತದೆ return sorted(list(set(numbers))) @given(st.lists(st.integers())) def test_sorting_properties(numbers): sorted_list = my_buggy_sort(numbers) # ಪ್ರಾಪರ್ಟಿ 1: ಔಟ್ಪುಟ್ ಸಾರ್ಟ್ ಆಗಿದೆ for i in range(len(sorted_list) - 1): assert sorted_list[i] <= sorted_list[i+1] # ಪ್ರಾಪರ್ಟಿ 2: ಎಲಿಮೆಂಟ್ಗಳು ಒಂದೇ ಆಗಿವೆ (ಇದು ಬಗ್ ಅನ್ನು ಕಂಡುಕೊಳ್ಳುತ್ತದೆ) assert Counter(numbers) == Counter(sorted_list) # ಪ್ರಾಪರ್ಟಿ 3: ಫಂಕ್ಷನ್ ಇಡೆಂಪೊಟೆಂಟ್ ಆಗಿದೆ assert my_buggy_sort(sorted_list) == sorted_list
ನೀವು ಈ ಪರೀಕ್ಷೆಯನ್ನು ಚಲಾಯಿಸಿದಾಗ, ಹೈಪೋಥಿಸಿಸ್ ಪ್ರಾಪರ್ಟಿ 2 ಗಾಗಿ ವಿಫಲವಾದ ಉದಾಹರಣೆಯನ್ನು ಶೀಘ್ರವಾಗಿ ಕಂಡುಕೊಳ್ಳುತ್ತದೆ, ಉದಾಹರಣೆಗೆ numbers=[0, 0]
. ನಮ್ಮ ಫಂಕ್ಷನ್ [0]
ಅನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ, ಮತ್ತು Counter([0, 0])
, Counter([0])
ಗೆ ಸಮನಾಗಿಲ್ಲ. ಶ್ರಿಂಕರ್ ವಿಫಲವಾದ ಉದಾಹರಣೆಯನ್ನು ಸಾಧ್ಯವಾದಷ್ಟು ಸರಳವಾಗಿರಿಸುತ್ತದೆ, ಇದರಿಂದ ಬಗ್ನ ಕಾರಣ ತಕ್ಷಣವೇ ಸ್ಪಷ್ಟವಾಗುತ್ತದೆ.
ಸನ್ನಿವೇಶ 3: ಸ್ಟೇಟ್ಫುಲ್ ಟೆಸ್ಟಿಂಗ್
ಕಾಲಾನಂತರದಲ್ಲಿ ಆಂತರಿಕ ಸ್ಥಿತಿ ಬದಲಾಗುವ ಆಬ್ಜೆಕ್ಟ್ಗಳಿಗೆ (ಡೇಟಾಬೇಸ್ ಕನೆಕ್ಷನ್, ಶಾಪಿಂಗ್ ಕಾರ್ಟ್, ಅಥವಾ ಕ್ಯಾಶ್ನಂತಹ) ಬಗ್ಗಳನ್ನು ಕಂಡುಹಿಡಿಯುವುದು ಅತ್ಯಂತ ಕಷ್ಟಕರವಾಗಿರುತ್ತದೆ. ದೋಷವನ್ನು ಪ್ರಚೋದಿಸಲು ನಿರ್ದಿಷ್ಟ ಕಾರ್ಯಾಚರಣೆಗಳ ಅನುಕ್ರಮ ಬೇಕಾಗಬಹುದು. ಹೈಪೋಥಿಸಿಸ್ ಈ ಉದ್ದೇಶಕ್ಕಾಗಿಯೇ `RuleBasedStateMachine` ಅನ್ನು ಒದಗಿಸುತ್ತದೆ.
ಇನ್-ಮೆಮೊರಿ ಕೀ-ವ್ಯಾಲ್ಯೂ ಸ್ಟೋರ್ಗಾಗಿ ಒಂದು ಸರಳ API ಅನ್ನು ಕಲ್ಪಿಸಿಕೊಳ್ಳಿ:
class SimpleKeyValueStore: def __init__(self): self._data = {} def set(self, key, value): self._data[key] = value def get(self, key): return self._data.get(key) def delete(self, key): if key in self._data: del self._data[key] def size(self): return len(self._data)
ನಾವು ಅದರ ವರ್ತನೆಯನ್ನು ಮಾದರಿಯಾಗಿರಿಸಿ ಸ್ಟೇಟ್ ಮೆಷಿನ್ನೊಂದಿಗೆ ಪರೀಕ್ಷಿಸಬಹುದು:
from hypothesis.stateful import RuleBasedStateMachine, rule, Bundle class KeyValueStoreMachine(RuleBasedStateMachine): def __init__(self): super().__init__() self.model = {} self.sut = SimpleKeyValueStore() # Bundle() ಅನ್ನು ನಿಯಮಗಳ ನಡುವೆ ಡೇಟಾವನ್ನು ರವಾನಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ keys = Bundle('keys') @rule(target=keys, key=st.text(), value=st.integers()) def set_key(self, key, value): self.model[key] = value self.sut.set(key, value) return key @rule(key=keys) def delete_key(self, key): del self.model[key] self.sut.delete(key) @rule(key=st.text()) def get_key(self, key): model_val = self.model.get(key) sut_val = self.sut.get(key) assert model_val == sut_val @rule() def check_size(self): assert len(self.model) == self.sut.size() # ಪರೀಕ್ಷೆಯನ್ನು ಚಲಾಯಿಸಲು, ನೀವು ಮೆಷಿನ್ ಮತ್ತು unittest.TestCase ನಿಂದ ಸಬ್ಕ್ಲಾಸ್ ಮಾಡಿ # pytest ನಲ್ಲಿ, ನೀವು ಸರಳವಾಗಿ ಟೆಸ್ಟ್ ಅನ್ನು ಮೆಷಿನ್ ಕ್ಲಾಸ್ಗೆ ನಿಯೋಜಿಸಬಹುದು TestKeyValueStore = KeyValueStoreMachine.TestCase
ಹೈಪೋಥಿಸಿಸ್ ಈಗ set_key
, delete_key
, get_key
, ಮತ್ತು check_size
ಕಾರ್ಯಾಚರಣೆಗಳ ಯಾದೃಚ್ಛಿಕ ಅನುಕ್ರಮಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತದೆ, ಅಸರ್ಶನ್ಗಳಲ್ಲಿ ಒಂದನ್ನು ವಿಫಲಗೊಳಿಸುವ ಅನುಕ್ರಮವನ್ನು ನಿರಂತರವಾಗಿ ಹುಡುಕುತ್ತದೆ. ಅಳಿಸಿದ ಕೀ ಅನ್ನು ಪಡೆದಾಗ ಸರಿಯಾಗಿ ವರ್ತಿಸುತ್ತದೆಯೇ, ಅನೇಕ ಸೆಟ್ಗಳು ಮತ್ತು ಡಿಲೀಟ್ಗಳ ನಂತರ ಗಾತ್ರವು ಸ್ಥಿರವಾಗಿದೆಯೇ, ಮತ್ತು ನೀವು ಹಸ್ತಚಾಲಿತವಾಗಿ ಪರೀಕ್ಷಿಸಲು ಯೋಚಿಸದಂತಹ ಅನೇಕ ಇತರ ಸನ್ನಿವೇಶಗಳನ್ನು ಅದು ಪರಿಶೀಲಿಸುತ್ತದೆ.
ಉತ್ತಮ ಅಭ್ಯಾಸಗಳು ಮತ್ತು ಸುಧಾರಿತ ಸಲಹೆಗಳು
- ಉದಾಹರಣೆ ಡೇಟಾಬೇಸ್: ಹೈಪೋಥಿಸಿಸ್ ಬುದ್ಧಿವಂತವಾಗಿದೆ. ಅದು ಬಗ್ ಅನ್ನು ಕಂಡುಕೊಂಡಾಗ, ಅದು ವಿಫಲವಾದ ಉದಾಹರಣೆಯನ್ನು ಸ್ಥಳೀಯ ಡೈರೆಕ್ಟರಿಯಲ್ಲಿ (
.hypothesis/
) ಉಳಿಸುತ್ತದೆ. ಮುಂದಿನ ಬಾರಿ ನೀವು ನಿಮ್ಮ ಪರೀಕ್ಷೆಗಳನ್ನು ಚಲಾಯಿಸಿದಾಗ, ಅದು ಮೊದಲು ಆ ವಿಫಲವಾದ ಉದಾಹರಣೆಯನ್ನು ಮರುಚಲಾಯಿಸುತ್ತದೆ, ಬಗ್ ಇನ್ನೂ ಇದೆಯೆಂದು ತಕ್ಷಣದ ಪ್ರತಿಕ್ರಿಯೆ ನೀಡುತ್ತದೆ. ನೀವು ಅದನ್ನು ಸರಿಪಡಿಸಿದ ನಂತರ, ಉದಾಹರಣೆಯು ಇನ್ನು ಮುಂದೆ ಮರುಚಲಾಯಿಸಲ್ಪಡುವುದಿಲ್ಲ. @settings
ನೊಂದಿಗೆ ಟೆಸ್ಟ್ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯನ್ನು ನಿಯಂತ್ರಿಸುವುದು: ನೀವು@settings
ಡೆಕೋರೇಟರ್ ಬಳಸಿ ಟೆಸ್ಟ್ ರನ್ನ ಅನೇಕ ಅಂಶಗಳನ್ನು ನಿಯಂತ್ರಿಸಬಹುದು. ನೀವು ಉದಾಹರಣೆಗಳ ಸಂಖ್ಯೆಯನ್ನು ಹೆಚ್ಚಿಸಬಹುದು, ಒಂದು ಉದಾಹರಣೆಯು ಎಷ್ಟು ಸಮಯದವರೆಗೆ ಚಲಿಸಬಹುದು ಎಂಬುದಕ್ಕೆ ಗಡುವು ನಿಗದಿಪಡಿಸಬಹುದು (ಅನಂತ ಲೂಪ್ಗಳನ್ನು ಹಿಡಿಯಲು), ಮತ್ತು ಕೆಲವು ಆರೋಗ್ಯ ತಪಾಸಣೆಗಳನ್ನು ಆಫ್ ಮಾಡಬಹುದು.@settings(max_examples=500, deadline=1000) # 500 ಉದಾಹರಣೆಗಳನ್ನು ಚಲಾಯಿಸಿ, 1-ಸೆಕೆಂಡ್ ಗಡುವು @given(...) ...
- ವೈಫಲ್ಯಗಳನ್ನು ಪುನರುತ್ಪಾದಿಸುವುದು: ಪ್ರತಿ ಹೈಪೋಥಿಸಿಸ್ ರನ್ ಒಂದು ಸೀಡ್ ಮೌಲ್ಯವನ್ನು ಮುದ್ರಿಸುತ್ತದೆ (ಉದಾ.,
@reproduce_failure('version', 'seed')
). ಒಂದು CI ಸರ್ವರ್ ಸ್ಥಳೀಯವಾಗಿ ಪುನರುತ್ಪಾದಿಸಲು ಸಾಧ್ಯವಾಗದ ಬಗ್ ಅನ್ನು ಕಂಡುಕೊಂಡರೆ, ನೀವು ಒದಗಿಸಿದ ಸೀಡ್ನೊಂದಿಗೆ ಈ ಡೆಕೋರೇಟರ್ ಅನ್ನು ಬಳಸಿ ಹೈಪೋಥಿಸಿಸ್ ಅನ್ನು ಅದೇ ಅನುಕ್ರಮದ ಉದಾಹರಣೆಗಳನ್ನು ಚಲಾಯಿಸಲು ಒತ್ತಾಯಿಸಬಹುದು. - CI/CD ಯೊಂದಿಗೆ ಸಂಯೋಜನೆ: ಹೈಪೋಥಿಸಿಸ್ ಯಾವುದೇ ನಿರಂತರ ಏಕೀಕರಣ (continuous integration) ಪೈಪ್ಲೈನ್ಗೆ ಪರಿಪೂರ್ಣವಾಗಿದೆ. ಉತ್ಪಾದನೆಯನ್ನು ತಲುಪುವ ಮೊದಲು ಅಸ್ಪಷ್ಟ ಬಗ್ಗಳನ್ನು ಕಂಡುಹಿಡಿಯುವ ಅದರ ಸಾಮರ್ಥ್ಯವು ಅದನ್ನು ಅಮೂಲ್ಯವಾದ ಸುರಕ್ಷತಾ ಜಾಲವನ್ನಾಗಿ ಮಾಡುತ್ತದೆ.
ಮನಸ್ಥಿತಿಯ ಬದಲಾವಣೆ: ಪ್ರಾಪರ್ಟಿಗಳಲ್ಲಿ ಆಲೋಚಿಸುವುದು
ಹೈಪೋಥಿಸಿಸ್ ಅನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳುವುದು ಕೇವಲ ಹೊಸ ಲೈಬ್ರರಿಯನ್ನು ಕಲಿಯುವುದಕ್ಕಿಂತ ಹೆಚ್ಚಾಗಿದೆ; ಇದು ನಿಮ್ಮ ಕೋಡ್ನ ಸರಿಯಾದತೆಯ ಬಗ್ಗೆ ಹೊಸ ರೀತಿಯಲ್ಲಿ ಯೋಚಿಸುವುದನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳುವುದಾಗಿದೆ. "ನಾನು ಯಾವ ಇನ್ಪುಟ್ಗಳನ್ನು ಪರೀಕ್ಷಿಸಬೇಕು?" ಎಂದು ಕೇಳುವ ಬದಲು, ನೀವು "ಈ ಕೋಡ್ನ ಬಗ್ಗೆ ಸಾರ್ವತ್ರಿಕ ಸತ್ಯಗಳು ಯಾವುವು?" ಎಂದು ಕೇಳಲು ಪ್ರಾರಂಭಿಸುತ್ತೀರಿ.
ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ಗುರುತಿಸಲು ಪ್ರಯತ್ನಿಸುವಾಗ ನಿಮಗೆ ಮಾರ್ಗದರ್ಶನ ನೀಡುವ ಕೆಲವು ಪ್ರಶ್ನೆಗಳು ಇಲ್ಲಿವೆ:
- ವಿರುದ್ಧ ಕಾರ್ಯಾಚರಣೆ ಇದೆಯೇ? (ಉದಾ., ಸೀರಿಯಲೈಸ್/ಡಿಸೀರಿಯಲೈಸ್, ಎನ್ಕ್ರಿಪ್ಟ್/ಡಿಕ್ರಿಪ್ಟ್, ಕಂಪ್ರೆಸ್/ಡಿಕಂಪ್ರೆಸ್). ಕಾರ್ಯಾಚರಣೆ ಮತ್ತು ಅದರ ವಿರುದ್ಧವನ್ನು ನಿರ್ವಹಿಸುವುದು ಮೂಲ ಇನ್ಪುಟ್ ಅನ್ನು ನೀಡಬೇಕು ಎಂಬುದು ಪ್ರಾಪರ್ಟಿಯಾಗಿದೆ.
- ಕಾರ್ಯಾಚರಣೆಯು ಇಡೆಂಪೊಟೆಂಟ್ ಆಗಿದೆಯೇ? (ಉದಾ.,
abs(abs(x)) == abs(x)
). ಫಂಕ್ಷನ್ ಅನ್ನು ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ಅನ್ವಯಿಸುವುದು ಒಮ್ಮೆ ಅನ್ವಯಿಸಿದಾಗ ಬರುವ ಫಲಿತಾಂಶವನ್ನೇ ನೀಡಬೇಕು. - ಅದೇ ಫಲಿತಾಂಶವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡಲು ಬೇರೆ, ಸರಳವಾದ ಮಾರ್ಗವಿದೆಯೇ? ನಿಮ್ಮ ಸಂಕೀರ್ಣ, ಆಪ್ಟಿಮೈಸ್ಡ್ ಫಂಕ್ಷನ್ ಸರಳ, ಸ್ಪಷ್ಟವಾಗಿ ಸರಿಯಾದ ಆವೃತ್ತಿಯಂತೆಯೇ ಅದೇ ಔಟ್ಪುಟ್ ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆಯೇ ಎಂದು ನೀವು ಪರೀಕ್ಷಿಸಬಹುದು (ಉದಾ., ನಿಮ್ಮ ಫ್ಯಾನ್ಸಿ ಸಾರ್ಟ್ ಅನ್ನು ಪೈಥಾನ್ನ ಅಂತರ್ನಿರ್ಮಿತ
sorted()
ವಿರುದ್ಧ ಪರೀಕ್ಷಿಸುವುದು). - ಔಟ್ಪುಟ್ ಬಗ್ಗೆ ಯಾವಾಗಲೂ ಏನು ಸತ್ಯವಾಗಿರಬೇಕು? (ಉದಾ., `find_prime_factors` ಫಂಕ್ಷನ್ನ ಔಟ್ಪುಟ್ ಕೇವಲ ಅವಿಭಾಜ್ಯ ಸಂಖ್ಯೆಗಳನ್ನು ಮಾತ್ರ ಹೊಂದಿರಬೇಕು, ಮತ್ತು ಅವುಗಳ ಗುಣಲಬ್ಧವು ಇನ್ಪುಟ್ಗೆ ಸಮನಾಗಿರಬೇಕು).
- ಸ್ಥಿತಿ ಹೇಗೆ ಬದಲಾಗುತ್ತದೆ? (ಸ್ಟೇಟ್ಫುಲ್ ಟೆಸ್ಟಿಂಗ್ಗಾಗಿ) ಯಾವುದೇ ಮಾನ್ಯವಾದ ಕಾರ್ಯಾಚರಣೆಯ ನಂತರ ಯಾವ ಇನ್ವೇರಿಯಂಟ್ಗಳನ್ನು ನಿರ್ವಹಿಸಬೇಕು? (ಉದಾ., ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ನಲ್ಲಿರುವ ಐಟಂಗಳ ಸಂಖ್ಯೆ ಎಂದಿಗೂ ಋಣಾತ್ಮಕವಾಗಿರಬಾರದು).
ತೀರ್ಮಾನ: ಆತ್ಮವಿಶ್ವಾಸದ ಹೊಸ ಮಟ್ಟ
ಹೈಪೋಥಿಸಿಸ್ನೊಂದಿಗೆ ಪ್ರಾಪರ್ಟಿ-ಬೇಸ್ಡ್ ಟೆಸ್ಟಿಂಗ್, ಉದಾಹರಣೆ-ಆಧಾರಿತ ಟೆಸ್ಟಿಂಗ್ ಅನ್ನು ಬದಲಿಸುವುದಿಲ್ಲ. ನಿರ್ಣಾಯಕ ವ್ಯಾಪಾರ ತರ್ಕ ಮತ್ತು ಚೆನ್ನಾಗಿ ಅರ್ಥಮಾಡಿಕೊಂಡ ಅವಶ್ಯಕತೆಗಳಿಗಾಗಿ ನಿಮಗೆ ಇನ್ನೂ ನಿರ್ದಿಷ್ಟ, ಕೈಬರಹದ ಪರೀಕ್ಷೆಗಳು ಬೇಕಾಗುತ್ತವೆ (ಉದಾ., "ದೇಶ X ನಿಂದ ಬಂದ ಬಳಕೆದಾರರು ಬೆಲೆ Y ಅನ್ನು ನೋಡಬೇಕು").
ಹೈಪೋಥಿಸಿಸ್ ಒದಗಿಸುವುದು ನಿಮ್ಮ ಕೋಡ್ನ ವರ್ತನೆಯನ್ನು ಅನ್ವೇಷಿಸಲು ಮತ್ತು ಅನಿರೀಕ್ಷಿತ ಎಡ್ಜ್ ಕೇಸ್ಗಳಿಂದ ರಕ್ಷಿಸಲು ಒಂದು ಶಕ್ತಿಯುತ, ಸ್ವಯಂಚಾಲಿತ ಮಾರ್ಗವಾಗಿದೆ. ಇದು ದಣಿವರಿಯದ ಪಾಲುದಾರನಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಯಾವುದೇ ಮನುಷ್ಯ ವಾಸ್ತವಿಕವಾಗಿ ಬರೆಯುವುದಕ್ಕಿಂತ ಹೆಚ್ಚು ವೈವಿಧ್ಯಮಯ ಮತ್ತು ಕುತಂತ್ರದ ಸಾವಿರಾರು ಪರೀಕ್ಷೆಗಳನ್ನು ರಚಿಸುತ್ತದೆ. ನಿಮ್ಮ ಕೋಡ್ನ ಮೂಲಭೂತ ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುವ ಮೂಲಕ, ನೀವು ಹೈಪೋಥಿಸಿಸ್ ಪರೀಕ್ಷಿಸಬಹುದಾದ ಒಂದು ದೃಢವಾದ ವಿವರಣೆಯನ್ನು ರಚಿಸುತ್ತೀರಿ, ಇದು ನಿಮ್ಮ ಸಾಫ್ಟ್ವೇರ್ನಲ್ಲಿ ಹೊಸ ಮಟ್ಟದ ಆತ್ಮವಿಶ್ವಾಸವನ್ನು ನೀಡುತ್ತದೆ.
ಮುಂದಿನ ಬಾರಿ ನೀವು ಫಂಕ್ಷನ್ ಬರೆಯುವಾಗ, ಉದಾಹರಣೆಗಳನ್ನು ಮೀರಿ ಯೋಚಿಸಲು ಒಂದು ಕ್ಷಣ ತೆಗೆದುಕೊಳ್ಳಿ. ನಿಮ್ಮನ್ನು ಕೇಳಿಕೊಳ್ಳಿ, "ನಿಯಮಗಳೇನು? ಯಾವುದು ಯಾವಾಗಲೂ ಸತ್ಯವಾಗಿರಬೇಕು?" ನಂತರ, ಅವುಗಳನ್ನು ಮುರಿಯಲು ಪ್ರಯತ್ನಿಸುವ ಕಠಿಣ ಕೆಲಸವನ್ನು ಹೈಪೋಥಿಸಿಸ್ಗೆ ಬಿಡಿ. ಅದು ಏನು ಕಂಡುಕೊಳ್ಳುತ್ತದೆ ಎಂದು ನಿಮಗೆ ಆಶ್ಚರ್ಯವಾಗುತ್ತದೆ, ಮತ್ತು ಅದರಿಂದ ನಿಮ್ಮ ಕೋಡ್ ಉತ್ತಮಗೊಳ್ಳುತ್ತದೆ.